/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fi.uba.algo3.tp3.modelo.actores;

import ar.uba.fi.algo3.titiritero.ObjetoVivo;
import ar.uba.fi.algo3.titiritero.Posicionable;
import fi.uba.algo3.tp3.modelo.servicios.ServicioJuego;
import fi.uba.algo3.tp3.modelo.actores.exceptions.*;
import fi.uba.algo3.tp3.vista.Observador;

/**
 *
 * @author ariel
 */
public abstract class Personaje implements ObjetoVivo, Posicionable {

    private ServicioJuego servicio;
    protected Integer x;
    protected Integer y;
    protected Integer posicionInicialX;
    protected Integer posicionInicialY;
    protected Integer sentidoX;
    protected Integer sentidoY;
    protected Integer distanciaDeColision;
    protected Observador observer;

    public Personaje(ServicioJuego servicio, Integer distanciaDeColision) {
        this.servicio = servicio;
        this.distanciaDeColision = distanciaDeColision;
        sentidoX = 0;
        sentidoY = 0;
        /*establece el moviemiento en un pixel*/
        //el pacman original arranca (no sé por qué) pa' la izquierda
        /* x e y se deberia inicializar fijo ya que siempre arranca
        en la misma posicion. */
    }

    // Aqui hay resetear la posicion de todos a su posicion inicial
    public abstract void reestablecer(ServicioJuego servicio);

    protected abstract void vivir(ServicioJuego servicio);

    @Override
    public void vivir() {
        // En la unica forma que va a pasar esto es cuando no haya obstaculos, porque sino
        // nunca va a poder irse fuera del rango, esto es generico para todos los personajes
        // por eso va aqui
        if ((this.x + distanciaDeColision) > servicio.obtenerLimiteHorizontal()) {
            x = distanciaDeColision;
            cambiarSentidoAHorizontalDerecha();
            x += sentidoX;
            y += sentidoY;
        } else if ((this.x - distanciaDeColision) < 0) {
            x=servicio.obtenerLimiteHorizontal()-distanciaDeColision;
            cambiarSentidoAHorizontalIzquierda();
            x += sentidoX;
            y += sentidoY;
        } else {
            vivir(servicio);
        }

    }

    @Override
    public int getX() {
        return x;
    }

    @Override
    public int getY() {
        return y;
    }

    //Los personajes pueden moverse horizontalmente o verticalmente no en diagonal
    protected void cambiarSentidoAHorizontalDerecha() {
        this.sentidoX = 1;
        this.sentidoY = 0;
    }

    protected void cambiarSentidoAHorizontalIzquierda() {
        this.sentidoX = -1;
        this.sentidoY = 0;
    }

    protected void cambiarSentidoAVerticalArriba() {
        this.sentidoX = 0;
        this.sentidoY = -1;
    }

    protected void cambiarSentidoAVerticalAbajo() {
        this.sentidoX = 0;
        this.sentidoY = 1;
    }

    public void setX(int x) throws PosicionInvalidaException {
        if ((x < 0) || (x > this.servicio.obtenerLimiteHorizontal())) {
            throw new PosicionInvalidaException();
        }
        this.x = x;

    }

    public void setY(int y) throws PosicionInvalidaException {
        if ((y < 0) || (y > this.servicio.obtenerLimiteVertical())) {
            throw new PosicionInvalidaException();
        }
        this.y = y;
        
    }

    public Integer getDistanciaDeColision() {
        return distanciaDeColision;
    }

    public void setObserver(Observador observer) {
        this.observer = observer;
    }

    public void setPosicionInicialX(Integer posicionInicialX) {
        this.posicionInicialX = posicionInicialX;
    }

    public void setPosicionInicialY(Integer posicionInicialY) {
        this.posicionInicialY = posicionInicialY;
    }

    public Integer getPosicionInicialX() {
        return posicionInicialX;
    }

    public Integer getPosicionInicialY() {
        return posicionInicialY;
    }


}
